import pdfplumber as pdf_parser
import pandas as pd
import numpy as np
import os
import re
import utils
from tqdm import tqdm


class PDFParser(object):

    def __init__(self, dir_pdf_filepath, page_from_to_config, output_path):
        # self.__filename = filename
        self.__pages = []  # 保存过滤后的文件页码, 根据指定条件
        self.__result = []  # 保存最终的数据
        self.dir_path = dir_pdf_filepath
        self.page_from_to_config = page_from_to_config
        self.output_path = output_path

    def parse_pdf(self, filename, page_from, page_to):
        """
        读取pdf文件, 从指定的开始和结束页码识别pdf中的table,
        :param filename:
        :param page_from:
        :param page_to:
        :return:
        """
        with pdf_parser.open(filename) as pdf:
            for i in tqdm(range(page_from, page_to), desc='Processing' + filename):
                current_page = pdf.pages[i]
                # text = current_page.extract_text()
                table = current_page.extract_table({
                    "vertical_strategy": "lines",
                    "horizontal_strategy": "lines",
                    "explicit_vertical_lines": [],
                    "explicit_horizontal_lines": [],
                    "snap_tolerance": 3,
                    "snap_x_tolerance": 3,
                    "snap_y_tolerance": 3,
                    "join_tolerance": 3,
                    "join_x_tolerance": 3,
                    "join_y_tolerance": 3,
                    "edge_min_length": 3,
                    "min_words_vertical": 3,
                    "min_words_horizontal": 1,
                    "keep_blank_chars": False,
                    "text_tolerance": 3,
                    "text_x_tolerance": 3,
                    "text_y_tolerance": 3,
                    "intersection_tolerance": 3,
                    "intersection_x_tolerance": 3,
                    "intersection_y_tolerance": 3,
                })
                print("table:", table)
                if table is None or len(table) <= 2:
                    continue
                else:
                    including_na_table = self.parse_empty_to_nan(table)
                    self.__result.append(including_na_table)
                self.__pages.append(i)
            # print(self.__result)
        return self

    def parse_pdf_filter(self):
        with pdf_parser.open(self.__filename) as pdf:
            for i in range(194, len(pdf.pages)):
                current_page = pdf.pages[i]
                # text = current_page.extract_text()
                table = current_page.extract_table()
                if table is None or len(table) <= 2:
                    continue
                else:
                    including_na_table = self.parse_empty_to_nan(table)
                    self.__result.append(including_na_table)
                self.__pages.append(i)
            print(self.__result)
        return self

    @staticmethod
    def parse_empty_to_nan(page_table):
        _table = []
        for row in page_table:
            _row = []
            for cell in row:
                if cell is None:
                    _row.append(np.nan)
                    continue
                elif re.match(r'^\s?$', cell):
                    _row.append(np.nan)
                else:
                    _row.append(cell)
            _table.append(_row)
        return _table

    def transform_data(self):
        _list = []
        for item in self.__result:
            df = pd.DataFrame(item)
            df.fillna(method='ffill', inplace=True)  # na单元格填充
            df.drop_duplicates()  # 删除每一页重复行
            _list.append(df)

        # df.drop_duplicates()
        self.__result = pd.concat(_list).drop_duplicates()
        return self

    # 指定输出路径文件,将结果保存到路径中
    def to_excel_file(self, file_path):
        if os.path.exists(file_path):
            print('预先删除历史文件数据')
            os.remove(file_path)
        else:
            # 如果文件所在路径不存在,返回False, 并创建路径
            is_file_path_exists = utils.create_file_path_not_exists(file_path)
            # 如果文件所在路径存在
            if is_file_path_exists:
                print('文件' + file_path + '不存在, 程序自动创建输出文件')
        self.__result.to_excel(file_path, header=False, index=False)
        self.__result = []

    # 暴露统一调用接口API
    def patch_generate(self):
        config = pd.read_json(self.page_from_to_config)
        for index, row in config.iterrows():
            input_pdf_file = self.dir_path + row["filename"]
            output_file = row["filename"].split('.')[0] + '.xlsx'
            self.parse_pdf(input_pdf_file, row["page_from"], row["page_to"]).transform_data().to_excel_file(
                self.output_path + output_file)
            print(row["filename"] + "处理完毕")


pdf_instance = PDFParser(dir_pdf_filepath="./product-book/",
                         page_from_to_config="page_from_to_config.json",
                         output_path="./output/"
                         )
pdf_instance.patch_generate()
